package com.adastros.buildingmanager.model.water;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import jxl.Cell;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.DateTime;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author developer
 */
public class DataModel {

  private final Properties properties = new Properties();
  private String fileName;
  private List meters;
  private List personnels;

  public DataModel() {
    properties.put("date", dateToString(new Date())) ;
    properties.put("personnel.1", "Victor") ;
    properties.put("personnel.2", "Walter") ;
    properties.put("personnel.3", "Juan") ;

    properties.put("meter.1", "General") ;
    properties.put("General.old.measurement", "120.342") ;
    
    // 200
    properties.put("meter.2", "201") ;
    properties.put("201.old.measurement", "120.342") ;
    
    properties.put("meter.3", "202") ;
    properties.put("202.old.measurement", "20.142") ;
    
    properties.put("meter.4", "203") ;
    properties.put("203.old.measurement", "30.543") ;
    
    properties.put("meter.5", "204") ;
    properties.put("204.old.measurement", "700.155") ;


    // 300
    properties.put("meter.6", "301") ;
    properties.put("301.old.measurement", "120.342") ;
    
    properties.put("meter.7", "302") ;
    properties.put("302.old.measurement", "20.142") ;
    
    properties.put("meter.8", "303") ;
    properties.put("303.old.measurement", "30.543") ;
    
    properties.put("meter.9", "304") ;
    properties.put("304.old.measurement", "700.155") ;

    // 400
    properties.put("meter.10", "401") ;
    properties.put("401.old.measurement", "120.342") ;
    
    properties.put("meter.11", "402") ;
    properties.put("402.old.measurement", "20.142") ;
    
    properties.put("meter.12", "403") ;
    properties.put("403.old.measurement", "30.543") ;
    
    properties.put("meter.13", "404") ;
    properties.put("404.old.measurement", "700.155") ;

    // 500
    properties.put("meter.14", "501") ;
    properties.put("501.old.measurement", "120.342") ;
    
    properties.put("meter.15", "502") ;
    properties.put("502.old.measurement", "20.142") ;
    
    properties.put("meter.16", "503") ;
    properties.put("503.old.measurement", "30.543") ;
    
    properties.put("meter.17", "504") ;
    properties.put("504.old.measurement", "700.155") ;
    

    // 600
    properties.put("meter.18", "601") ;
    properties.put("601.old.measurement", "120.342") ;
    
    properties.put("meter.19", "602") ;
    properties.put("602.old.measurement", "20.142") ;
    
    properties.put("meter.20", "603") ;
    properties.put("603.old.measurement", "30.543") ;
    
    properties.put("meter.21", "604") ;
    properties.put("604.old.measurement", "700.155") ;

    
    // 700
    properties.put("meter.22", "701") ;
    properties.put("701.old.measurement", "120.342") ;
    
    properties.put("meter.23", "702") ;
    properties.put("702.old.measurement", "20.142") ;
    
    properties.put("meter.24", "703") ;
    properties.put("703.old.measurement", "30.543") ;
    
    properties.put("meter.25", "704") ;
    properties.put("704.old.measurement", "700.155") ;
    
    readMeterNames();
    readPesonnels();    
  }
  
  public DataModel(String fileName) throws FileNotFoundException, IOException {
    InputStream in = new FileInputStream(fileName);

    this.fileName = fileName;

    try {
      properties.load(in);
      readMeterNames();
      readPesonnels();
    } finally {
      in.close();
    }
  }

  public void setFileName(String fileName) {
    this.fileName = fileName ;
  }
  
  public void save() throws IOException {
    save(fileName);
  }
  
  public void save(String fileName) throws FileNotFoundException, IOException {
    OutputStream out = new FileOutputStream(fileName);

    try {
      Date date = new Date() ;
      Calendar calendar = Calendar.getInstance();      
      
      calendar.setTime(date);
      String timeStamp = calendar.get(Calendar.DAY_OF_MONTH) + "-" + calendar.get(Calendar.MONTH) + "-" + calendar.get(Calendar.YEAR) + " " + 
                         calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE) + ":" + calendar.get(Calendar.SECOND) ;
      properties.setProperty("time.stamp", timeStamp) ;
      properties.store(out, "Datos de medida");
    } finally {
      out.close();
    }
  }

  private void readMeterNames() {
    // Vamos a crear la tabla de medidores
    meters = new ArrayList();
    int i = 1;
    String meterName = properties.getProperty("meter." + i);

    while (null != meterName) {
      meters.add(meterName);
      ++i;
      meterName = properties.getProperty("meter." + i);
    }
  }

  public int getPersonnelCount() {
    return personnels.size() ;
  }
  
  public String getPersonnel(int index) {
    return (String) personnels.get(index) ;
  }
  
  private void readPesonnels() {
    personnels = new ArrayList();

    int i = 1;
    String personnelName = properties.getProperty("personnel." + i);

    while (null != personnelName) {
      personnels.add(personnelName);
      ++i;
      personnelName = properties.getProperty("personnel." + i);
    }
  }

  public int getNumOfMeters() {
    return meters.size();
  }

  public String getMeterName(int i) {
    return (String) meters.get(i);
  }

  public static String dateToString(Date date) {
    Calendar calendar = Calendar.getInstance();

    calendar.setTime(date);

    int day = calendar.get(Calendar.DAY_OF_MONTH);
    int month = calendar.get(Calendar.MONTH);
    int year = calendar.get(Calendar.YEAR);

    return day + "-" + month + "-" + year;
  }

  public static Date stringToDate(String dateString) {
    int index1 = dateString.indexOf('-') ;
    int index2 = dateString.lastIndexOf('-') ;
    
    String day = dateString.substring(0, index1);
    String month = dateString.substring(index1 + 1, index2);
    String year = dateString.substring(index2 + 1);

    Calendar calendar = Calendar.getInstance();

    calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day));
    calendar.set(Calendar.MONTH, Integer.parseInt(month));
    calendar.set(Calendar.YEAR, Integer.parseInt(year));

    return calendar.getTime();
  }

  public Date getDate() {
    Date date = new Date();

    String dateString = properties.getProperty("date");

    if (null == dateString) {
      date = stringToDate(dateString);
    }

    return date;
  }

  public void setDate(Date date) {
    properties.setProperty("date", dateToString(date)) ;
  }

  public String getActivePersonnel() {
    return properties.getProperty("active.personnel");
  }

  public void setActivePersonnel(String activePersonnel) {
    properties.setProperty("active.personnel", activePersonnel);
  }

  public String getOldMeasurement(int meter) {
    return getOldMeasurement((String) meters.get(meter));
  }

  public String getOldMeasurement(String meterName) {
    return properties.getProperty(meterName + ".old.measurement", "").trim();
  }

  public void setOldMeasurement(int meter, String value) {
     setOldMeasurement((String) meters.get(meter), value) ;
  }

  public void setOldMeasurement(String meterName, String value) {
    properties.setProperty(meterName + ".old.measurement", value);
  }
  
  public String getMeasurement(int meter) {
    return getMeasurement((String) meters.get(meter));
  }

  public String getMeasurement(String meterName) {
    return properties.getProperty(meterName + ".measurement", "").trim();
  }

  public void setMeasurement(int meter, String value) {
    setMeasurement((String) meters.get(meter), value);
  }

  public void setMeasurement(String meterName, String value) {
    properties.setProperty(meterName + ".measurement", value);
  }
  
  public boolean isAllSet() {
    return true ;
  }
  
  public void moveNewToOld() {
    for (int i = 0 ; i < getNumOfMeters() ; ++i) {
      String measure = getMeasurement(i) ;
      setOldMeasurement(i, measure);
      setMeasurement(i, "");
    }
  }
  
  public void exportToXLS(String fileName) throws IOException, BiffException, WriteException {
    File file = new File(fileName) ;
    File destFile = new File(fileName + ".1") ;
    WritableWorkbook workbook ;
    
    if (file.exists())
      workbook =  Workbook.createWorkbook(destFile, Workbook.getWorkbook(file)) ;
    else
      workbook = Workbook.createWorkbook(destFile) ;
    
    WritableSheet sheet = workbook.getSheet(0) ;

    sheet.insertColumn(1);
    
    int row = 1 ;
    int col = 0 ;
    
    sheet.addCell(new DateTime(1, 0, getDate()));
    sheet.addCell(new Label(1, 1, getActivePersonnel()));
    //sheet.addCell(new jxl.write.Number(2, row, Double.parseDouble(getMeasurement("General"))));
    
    for (int i = 0 ; i < getNumOfMeters() ; ++i) {
      String measurement = getMeasurement(i) ;
      
      if (!measurement.isEmpty())
        sheet.addCell(new jxl.write.Number(1, i + 2, Double.parseDouble(measurement)));
    }
    
    workbook.write();
    workbook.close();
  }
}
